package cn.itcast.cglib;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * 模拟一个剧组
 * @author zhy
 *
 */
public class Client {

	public static void main(String[] args) {
		final Actor actor = new Actor();
		
		
		/* 使用CGLIB产生代理对象，要求被代理对象不能是final修饰的（最终类）
		 * 	它是第三方提供。
		 * 明确：
		 * 	能使用jdk官方的，就不使用第三方的。
		 *  能使用Proxy，就不使用CGLIB。
		 * 基于子类的动态代理
		 *步骤：
		 *	1.导入必须的jar包
		 *
		 * 创建代理对象：
		 * 	使用：
		 * 	Enhancer类的create方法。
		 * 该方法有2个参数
		 * 	第一个：被代理对象的字节码
		 *  第二个：如何代理
		 */
		
		Actor proxyActor = (Actor) Enhancer.create(actor.getClass(),new MethodInterceptor() {
			/**
			 * 执行被代理对象的任何方法都会经过该方法
			 * 参数详解：
			 * 	Object proxy  ： 和Proxy中invoke方法参数作用一样
				Method method ： 和Proxy中invoke方法参数作用一样
				Object[] args ： 和Proxy中invoke方法参数作用一样
				MethodProxy methopdProxy：当前执行方法的代理对象
			       返回值：
			   	当前执行方法的返回值
			 */
			@Override
			public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methopdProxy) throws Throwable {
				//先取出给了多少钱
				Float money = (Float)args[0];
				//判断执行的是哪个方法
				if("basicAct".equals(method.getName())){
					if(money > 2000){
						method.invoke(actor, money/1.5f);
					}
				}
				if("dangerAct".equals(method.getName())){
					if(money > 6000){
						method.invoke(actor, money/1.5f);
					}
				}
				return null;
			}
		});
		proxyActor.basicAct(4000f);
		proxyActor.dangerAct(12000f);
	}
}
